package com.mk.ssm.service.impl;

import com.github.pagehelper.PageHelper;
import com.mk.ssm.aop.MethodCache;
import com.mk.ssm.bean.dto.UserDto;
import com.mk.ssm.bean.entity.Role;
import com.mk.ssm.bean.entity.User;
import com.mk.ssm.cache.RedisCache;
import com.mk.ssm.enums.ResultEnum;
import com.mk.ssm.exception.BizException;
import com.mk.ssm.mapper.UserMapper;
import com.mk.ssm.service.PasswordHelper;
import com.mk.ssm.service.RoleService;
import com.mk.ssm.service.UserService;
import com.mk.ssm.utils.Constants;
import com.mk.ssm.utils.ResultUtil;
import com.mk.ssm.utils.TimeUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;

/**
 * <p>Resource: yankee
 * <p>Date: 17-4-3
 * <p>Version: 1.0
 */
@Service("userService")
public class UserServiceImpl implements UserService {
    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordHelper passwordHelper;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisCache cache;

    /**
     * 创建用户
     *
     * @param user
     */
    public int createUser(User user) {
        Integer res;
        UserDto userDto = new UserDto();
//        userDto.setRoleIds(user.getRoleIdsStr());
        user.setAble(Constants.ABLE_CONFIG.DEFAULT_ABLE);
        user.setLocked(Constants.LOCKED_CONFIG.DEFAULT_LOCKED);
        user.setCreateAt(TimeUtils.getCurrentTimeInString(TimeUtils.DATE_FORMAT_DATE_S));
        //判断传入的对象中的参数是否齐全
        if(user.getUsername() != null && !"".equals(user.getUsername())
                && user.getPassword() != null && !"".equals(user.getPassword())
                && user.getRoleIds() != null && user.getOrgId() != null
                && user.getName() != null && !"".equals(user.getName())
                && user.getType() != null && !"".equals(user.getType())
                && user.getSex() != null && !"".equals(user.getSex())
                && user.getRoleIds().size() > 0 ) {
            //添加用户姓名时不能有%
            if(!ResultUtil.haveName(user.getName()))
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM10;
            else if(!ResultUtil.isChinese(user.getUsername()))
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM07;
            else {
                User user1 = userMapper.findByUsername(user.getUsername(), null);
                if (user1 == null) {
                    System.out.println("user=" + user);
                    //加密密码
                    passwordHelper.encryptPassword(user);
                    try {
                        BeanUtils.copyProperties(userDto, user);
                        Integer sum = 0;
                        //在数据库中去查找所有传入的角色信息是否存在
                        for (int j = 0; j < user.getRoleIds().size(); j++) {
                            Role role = roleService.findOne(user.getRoleIds().get(j));
                            if (role != null)
                                sum++;
                        }
                        //根据对象来查找所有的组织信息
//                        Organization organization = organizationDao.findOrgById(user.getOrgId(), Constants.ABLE_CONFIG.ABLE);
                        if (/*organization != null &&*/ sum == user.getRoleIds().size()) {
                            userDto.setRoleIds(user.getRoleIdsStr());
                            res = userMapper.createUser(userDto);
                            return res;
                        }
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM06;
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM03;
                    }
                } else
                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
            }
        }else{
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
        }
        return res;
    }

    @Override
    public int createUsers(List<User> list) {
        Integer res;
        if(list != null) {
            for (User user : list) {
                createUser(user);
            }
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM04;
        }else
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM03;
        return res;
    }

    @Override
    public int updateUser(User user) {
        Integer res;
        UserDto userDto = new UserDto();
        try {
            BeanUtils.copyProperties(userDto, user);
            //下面三个值默认不为空，修改时若不传入就设定为null
            if(user.getLocked() == null){
                userDto.setLocked(null);
            }
            if(user.getAble() == null){
                userDto.setAble(null);
            }
            if(user.getOrgId() == null){
                userDto.setOrgId(null);
            }else{
                //去数据库中查找所有的组织部门信息，核对传入的部门orgId
//                Organization organization = organizationDao.findOrgById(user.getOrgId(), Constants.ABLE_CONFIG.ABLE);
                //如果数据库中查不到该条信息，赋值为null
//                if(organization == null)
//                    userDto.setOrgId(null);
//                else
//                    userDto.setOrgId(user.getOrgId());
            }
            //去数据库中查找所有的角色信息，判断传入的角色信息是否存在
            Integer sum = 0;
            for (int j = 0; j < user.getRoleIds().size(); j++) {
                Role role = roleService.findOne(user.getRoleIds().get(j));
                if(role != null)
                    sum++;
            }
            //判断查询结果跟传入的值的长度是否一致，一致就赋值
            if(sum == user.getRoleIds().size())
                userDto.setRoleIds(user.getRoleIdsStr());
            else
                userDto.setRoleIds(null);
        } catch (IllegalAccessException e) {
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
            e.printStackTrace();
            return res;
        } catch (InvocationTargetException e) {
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            e.printStackTrace();
            return res;
        }
        if(user.getId() != null) {
            if(user.getName() != null && !ResultUtil.haveName(user.getName()))
                return ResultUtil.RESULT_CONFIG.RESULT_NUM10;
            if(user.getUsername() != null && !"".equals(user.getUsername())) {
                if(!ResultUtil.isChinese(user.getUsername()))
                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM07;
                else {
                    User user1 = userMapper.findByUsername(user.getUsername(), Constants.ABLE_CONFIG.ABLE);
                    if (user1 == null) {
                        res = userMapper.updateUser(userDto);
                    } else if (user1 != null && user1.getId() == user.getId()) {
                        res = userMapper.updateUser(userDto);
                    } else {
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM06;
                    }
                }
            }else if((userDto.getUsername() == null || "".equals(userDto.getUsername()))
                    && (userDto.getPassword() == null || "".equals(userDto.getPassword()))
                    && (userDto.getName() == null || "".equals(userDto.getName()))
                    && (userDto.getSex() == null || "".equals(userDto.getSex()))
                    && (userDto.getSalt() == null ||"".equals(userDto.getSalt()))
                    && (userDto.getCreateAt() == null || "".equals(userDto.getCreateAt()))
                    && (userDto.getUpdateAt() == null || "".equals(userDto.getUpdateAt()))
                    && (userDto.getType() == null || "".equals(userDto.getType()))
                    && userDto.getAble() == null && userDto.getLocked() == null
                    && (userDto.getRoleIds() == null || "".equals(userDto.getRoleIds()))
                    && userDto.getOrgId() == null){
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM06;
            }else
                res = userMapper.updateUser(userDto);
        }else{
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
        }
        return res;
    }

    @Override
    public int deleteUser(Long userId) {
        Integer res;
        User user = userMapper.findOne(userId, Constants.ABLE_CONFIG.ABLE);
        if(user != null) {
            if("admin".equals(user.getUsername())){
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            }else
                res = userMapper.deleteUser(userId, Constants.ABLE_CONFIG.UNABLE);
        }else{
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
        }
        return res;
    }

    /**
     * 修改密码
     *
     * @param userId
     * @param newPassword
     */
    public int changePassword(Long userId,String oldPassword, String newPassword) {
        Integer res = 0;
//        User user = userMapper.findOne(userId,Constants.ABLE_CONFIG.ABLE);
//        if(userId != null && user != null) {
//            if(oldPassword != null && !"".equals(oldPassword) && passwordsMatch(user,oldPassword)) {
//                if (newPassword != null && !"".equals(newPassword)) {
//                    user.setPassword(newPassword);
//                    passwordHelper.encryptPassword(user);
//                    res = updateUser(user);
//                } else {
//                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
//                }
//            }else{
//                res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
//            }
//        }else{
//            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
//        }
        return res;
    }


    /**
     * wang
     * @param userId
     * @param userName
     * @param oldPassword
     * @param newPassword
     * @return
     */
    public int passwordChange(Long userId,String userName,String oldPassword, String newPassword) {
        Integer res;
        User user = userMapper.findOne(userId, Constants.ABLE_CONFIG.ABLE);
//        if (!ResultUtil.isChinese(user.getUsername()))
//            return ResultUtil.RESULT_CONFIG.RESULT_NUM07;
        //登录名判重
        if (userName != null && !"".equals(userName)) {
            //判断输入的登录名是否为中文
            if(!ResultUtil.matchUserName(userName)){
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM07;
            }else {
                User user1 = userMapper.findByUsername(userName, Constants.ABLE_CONFIG.ABLE);
                if (user1 != null) {
                    if (user.getId() != userId) {
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM08;
                    } else {
                        //判断用户旧密码并修改
                        res = matchOldPassAndChangPass(oldPassword, userName, newPassword, user);
                    }
                } else if (user1 == null) {
                    res = matchOldPassAndChangPass(oldPassword, userName, newPassword, user);
                } else {
                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM09;
                }
            }
        }else {
            //user.setUsername(userName);
            //没有传入用户名
            if (userId != null && user != null) {
                if (oldPassword != null && !"".equals(oldPassword) && passwordsMatch(user, oldPassword)) {
                    if (newPassword != null && !"".equals(newPassword)) {
                        user.setPassword(newPassword);
                        passwordHelper.encryptPassword(user);
                        res = updateUser(user);
                    } else {
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
                    }
                } else {
                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
                }
            } else {
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
            }
        }
        return res;
    }

    @Override
    @MethodCache(clz = User.class)
    public User findOne(Long userId) {
        return userMapper.findOne(userId, Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    @MethodCache(isCollection = 1, clz = User.class, expire = 300) // 触发缓存aop，返回结果是集合，集合内对象类型是User，缓存过期时间5分钟
    public List<User> findAll() {
        return userMapper.findAll(Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    @MethodCache(clz = User.class)
    public User findByUsername(String username) {
        return userMapper.findByUsername(username, Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    @MethodCache(isCollection = 1, clz = String.class)
    public List<String> findRoles(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_LIST;
        }
        return roleService.findRoles(user.getRoleIds()); // 目的在于：程序健壮性（user.roleIds可不算数，需要去role中验证/获取）
    }

    @Override
    @MethodCache(isCollection = 1, clz = String.class)
    public List<String> findPermissions(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_LIST;
        }
        return roleService.findPermissions(user.getRoleIds());
    }

    @Override
    @MethodCache(isCollection = 1, clz = User.class)
    public List<User> findUsers(Long id,String username){
        // 参数处理 （idOrUsername）
        //User user = new User();
        //if (StringUtils.isNumeric(idOrUsername)) {
        //user.setId(Long.parseLong(idOrUsername));
        //} else {
        //user.setUsername(idOrUsername);
        //}

        // 业务处理
        List<User> users = userMapper.findUsers(id,username, Constants.ABLE_CONFIG.ABLE);
        if (users == null || users.size() == 0) {
            throw new BizException(ResultEnum.DB_SELECTONE_IS_NULL.getMsg());
        }
        return users;
    }

    @Override
    public boolean isValidUser(String username, String password) {
        User user = findByUsername(username);
        if (user == null){
            return false;
        }
        User checkUser = new User();
        checkUser.setUsername(username);
        checkUser.setPassword(password);
        passwordHelper.encryptPassword(checkUser);
        return user.getPassword().equals(checkUser.getPassword());
    }

    @Override
    public boolean passwordsMatch(User user, String password) {
        User cUser = findByUsername(user.getUsername());
        cUser.setPassword(password);
        return passwordHelper.passwordsMatch(user,cUser);
    }

    /**
     * 根据部门id和用户姓名来模糊查询用户信息
     * @param orgId
     * @param name
     * @return
     */
    @Override
    public List<User> findUsersByOrg(Long orgId,String name,Integer pageNumber,Integer pageSize) {
//        UserAndOrg userAndOrg = new UserAndOrg();
//        if(orgId != null){
//            userAndOrg.setOrgId(orgId);
//        }
//        if(name != null && "".equals(name)){
//            userAndOrg.setName(name);
//        }
//        System.out.println("####################################");
//        System.out.println(userAndOrg);
//        Integer start = 0;
//        if(page != null && page != 0 && rows != null && rows != 0){
//            start = (page - 1) * rows;
//        }
        if(pageNumber != null && pageSize != null)
            PageHelper.startPage(pageNumber,pageSize);
        return userMapper.findUsersByOrg(orgId,name, Constants.ABLE_CONFIG.ABLE/*,start,rows*/);
    }

    @Override
    public int countNum(Long orgId,String name) {
        return userMapper.countNum(orgId,name, Constants.ABLE_CONFIG.ABLE);
    }

    //判断用户的旧密码是否正确，并修改密码
    private int matchOldPassAndChangPass(String oldPassword,String userName,String newPassword,User user){
        if (oldPassword != null && !"".equals(oldPassword) && passwordsMatch(user, oldPassword)) {
            if (newPassword != null && !"".equals(newPassword)) {
                user.setUsername(userName);
                user.setPassword(newPassword);
                passwordHelper.encryptPassword(user);
                return updateUser(user);
            }
            else {
                return  ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            }
        }else {
            return  ResultUtil.RESULT_CONFIG.RESULT_NUM05;
        }
    }
}
